// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.mall;
import java.util.HashMap;
import java.util.Vector;

import com.eva.epc.common.util.ESerializable;
import com.eva.framework.Processor;
import com.eva.framework.Processor.User;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.ONHelper;
import com.eva.framework.utils.SNHelper;

/**
 * eva.epc开发框架的某些通用功能处理器.<br>
 * 一些要被客户端调用的通用功能，建议放在本类中实现.<br>
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class FWBaseProcessor implements Processor
{
	/** 此值用于单号生成时是否需要自动生成（非此值则被认为不需要自动生成） */
	public final static String PREDEFINE_AUTO = "AUTO";
	public static DBShell db;

	/** 系统配置信息存放表名 */
	private static String dbConfTableName = "esys_conf";//TableConst.DEFAULT_T_SYS_CONF;
	/** 系统配置信息缓存,客户端与服务端都采用缓存，这样可以保证需要使新的配置生效必须重新启动两边的服务 */
	private static HashMap<String,DBConfDTO> dbConfCache = new HashMap();
	

	public FWBaseProcessor()
	{
		this(new DBShell());
	}
	/**
	 * @param database 配置好的数据库
	 */
	public FWBaseProcessor(DBShell database)
	{
		this.db = database;
	}

	/**
	 * 处理器的核心实现方法.<br>
	 * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
	 * action_id进行对应动作的处理，以完全本次操作请求.
	 * 
	 * @param job_dispatch_id 作业调度ID
	 * @param action_id 动作ID
	 * @param Object newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
	 * @param Object oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
	 * @return 任意类型返回值
	 * @throws Exception
	 */
	public Object process(int job_dispatch_id,int action_id,Object nw,Object old,User pm)
		throws Exception
	{
		Object ret = null;
		switch (job_dispatch_id)
		{
//			//更新数据库，提供给客户直接传递过来SQL语句即可完成更新
//			//参见客户端类：FWUtils.updatePrepareSql(..)方法
//			case JobDispatchConst.SINGLE_SQL_UPDATE:
//				if(old!=null)
//					db.update((String)nw,(Object[])old,true);
//				else
//					db.update((String)nw,new Object[]{},true);
//				break;
				
//				//提供给客户端以实现一组SQL语句的批量更新
//				//参见客户端类：updatePrepareSql(List,List, boolean)方法
//			case JobDispatchConst.BATCH_SQL_UPDATE:
//				//多条SQL是否作为事务处理（是 则表示任一条语句执行时出现异常
//				//即全总回滚所有操作，否则只回滚出现异常的语句更新）
//				boolean rollbackIfZero = true;
//				Object[] objs = (Object[])nw;
//				List sqls,values;
//				rollbackIfZero = ((Boolean)objs[0]).booleanValue();
//				sqls = (List)objs[1];
//				values = (List)objs[2];
//				db.update(sqls, values, rollbackIfZero);
//				break;
				
//				//批量获取sql查询结果的方法，按照原先sql提交的顺序，返回对应的结果集
//			case JobDispatchConst.GET_SQL_RESULT_BAT:
//				ret = batchQuery((Vector)nw);
//				break;
				
//				//获取存放于数据库表中的系统配置信息
//			case JobDispatchConst.GET_CONF:
//				ret = getDBConf((String)nw);
//				break;

				//提供给客户端以便据传过来的SQL语句查询出结果集并返回给客户端
			case JobDispatchConst.GET_DATA:
//				LoggerFactory.getLog().debug("sys_get_sql="+nw.toString());
				ret = db.queryData(nw.toString());
				break;
				
//			case JobDispatchConst.SYS_LOG:
//				moveLogToHistory();
//				break;
			default:
				throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
		}
		return ret;
	}

	/**
	 * 获取存放于数据库表中的系统配置信息.
	 * 
	 * @param sysid 系统配置ID
	 * @return 获取的配置信息，如果没有则返回null
	 */
	public static DBConfDTO getDBConf(String sysid) throws Exception
	{
		DBConfDTO ret = dbConfCache.get(sysid);
		if(ret == null)
		{
			Vector vec = db.queryData(
					"select "+ESYS_CONF.conf_val+","+ESYS_CONF.default_val+","
					+ESYS_CONF.other1+","+ESYS_CONF.other2+","+ESYS_CONF.other3
					+" from "+dbConfTableName+" where "+ESYS_CONF.conf_id+"=?"
					,new Object[]{sysid});
			if(vec.size()>0)
			{
				vec = (Vector)vec.get(0);
				ret = new DBConfDTO();
				ret.setConfId(sysid);
				int i=0;
				ret.setConfVal(vec.get(i++).toString());
				ret.setDefaultVal(vec.get(i++).toString());
				ret.setOther1(vec.get(i++).toString());
				ret.setOther2(vec.get(i++).toString());
				ret.setOther3(vec.get(i++).toString());
				dbConfCache.put(sysid,ret);
			}
			else
				return null;
		}
		return ret;
	}

//	/**
//	 * 批量获取sql查询结果的方法，按照原先sql提交的顺序，返回对应的结果集.
//	 * 
//	 * @param sqls 待查询的各个sql语句
//	 * @return 各个语句对应的结果，结构是Vector<每条语句查询出的结果集>
//	 * @see DBShell#queryData(String)
//	 */
//	public static Vector<Vector> batchQuery(Vector sqls) throws Exception
//	{
//		Vector<Vector> values = new Vector(sqls.size());
//		for (int i = 0; i < sqls.size(); i++)
//			values.add(db.queryData((String)sqls.get(i)));
//		return values;
//	}

	/**
	 * 获取单号（本方法是据xtpzb中的配置信息来生成单号的，更加智能和灵活）.<br>
	 * 如果要自动生成，必须在系统配置表中对应记录中设置其他属性的值＝0或者＝1，否则会有问题
	 * 同样的其配置的值是＝AUTO(要求自动生成),否为MANUAL.<br>
	 * @param sysID 系统常量
	 * @param dhmc 如果需要自动生成的单号名称,对于是按序列号生成则为zc_sequence中的名称，如按单号规则生成则为dhscxx表中的信息
	 * @param defaultDh 默认的单号，如果手工输入则为输入的单号，否则为其他值
	 * @return 获得的单号，
	 * @throws Exception 格式问题,单号规则未定义问题,最大值问题
	 */
	public static String getONAuto(String sysID,String dhmc,String defaultDh) throws Exception
	{
		String[] ret=getMultiONAuto(sysID, dhmc, new String[]{defaultDh}, 1);
		return ret==null||ret.length<=0?null:ret[0];
	}
	/**
	 * 批量获取单号（本方法是据xtpzb中的配置信息来生成单号的，更加智能和灵活）.<br>
	 * 单号是形如：“CGDD201101140004”这样的由日期和流水号组成的字符串.<br>
	 * 
	 * @param sysID 据此系统ID查询配置信息（如果返回的配置信息是 {@link #PREDEFINE_AUTO} 则表示要自动生成DH，逻辑
	 * 正常执行，否则返回值是 defaultDhs
	 * @param dhmc 存放于dhscxx表中的单号定义主键值
	 * @param defaultDhs 默认传过来的单号，如果配置指明不需要自动生成则直接返回本字段值作为返回值
	 * @param cnt 批量生成的数量
	 * @return
	 * @throws Exception
	 * @see ONHelper.OrderNumberDTO
	 * @see SNHelper#getMultiSerialNumber(String, int)
	 * @see ONHelper#getMultiON(String, int)
	 */
	public static String[] getMultiONAuto(String sysID,String dhmc,String[] defaultDhs,int cnt) throws Exception
	{
		String[] dhs = defaultDhs;
		DBConfDTO id = getDBConf(sysID);
		if(id != null && id.getConfVal().toUpperCase().equals(PREDEFINE_AUTO))
		{
			//要求自动生成，并且当前值＝默认显示值时才取自动生成的号，否则保留原来的
			//这主要考虑今后系统的灵活性，即可手工输入也可自动输入
			if(dhs==null || dhs.length ==0 || dhs[0]==null
					|| dhs[0].trim().length() == 0 || dhs[0].equals(id.getDefaultVal()))
			{
				/** 在其他属性中保存要生成的类型 */
				//0 表示在esys_SN表里找到SN名并使用序列号生成
				int type = Integer.parseInt(id.getOther1());
				if(type == 0)
					dhs = SNHelper.getMultiSN(dhmc, cnt);
				//0 表示在esys_ON表里找到ON名并使用单号生成
				else if(type == 1)
					dhs = ONHelper.getMultiON(dhmc,cnt);
			}
		}
		return dhs;
	}
	
	/**
	 * 存放在DB中的配置信息数据传输类（对应于数据库表esys_conf）.
	 * 
	 * @version 1.0
	 */
	public static class DBConfDTO implements ESerializable
	{
		/** 系统配置ID */
	    protected String conf_id;
	    /** 系统配置值 */
	    protected String conf_val;
	    /**  默认显示 */
	    protected String default_val;

		/** 其他属性 */
	    protected String other1;
	    /** 配置说明 */
	    protected String bz;
	    /** 其他属性2 */
	    protected String other2;
	    /** 其他属性3 */
	    protected String other3;

	    public String getDefaultVal()
	    {
	        return default_val;
	    }
	    public void setDefaultVal(String defaultVal)
	    {
	        this.default_val = defaultVal;
	    }

	    public String getConfId()
	    {
	        return conf_id;
	    }
	    public String getConfVal()
	    {
	        return conf_val;
	    }
	    
	    public void setConfVal(String conf_val)
	    {
	        this.conf_val = conf_val;
	    }
	    public void setConfId(String conf_id)
	    {
	        this.conf_id = conf_id;
	    }

	    public String getOther2()
	    {
	        return other2;
	    }
	    public void setOther2(String other2)
	    {
	        this.other2 = other2;
	    }

	    public String getOther3()
	    {
	        return other3;
	    }
	    public void setOther3(String other3)
	    {
	        this.other3 = other3;
	    }

	    public String getOther1()
	    {
	        return other1;
	    }
	    public void setOther1(String other1)
	    {
	        this.other1 = other1;
	    }
	    
	    public String getBz()
		{
			return bz;
		}
		public void setBz(String bz)
		{
			this.bz = bz;
		}
	}
	
	// 数据库表esys_conf表字段定义（与数据库中的表字段严格对应，请保持一致！）
	public interface ESYS_CONF
	{
		String conf_id ="conf_id";
		String conf_val ="conf_val";
		String default_val ="default_val";
		String other1 ="other1";
		String bz ="bz";
		String other2 ="other2";
		String other3 ="other3";
		String gen_time ="gen_time";
	}
	
	/**
	 * 本类中用到的作业调度常量表.
	 * 
	 * @version 1.0
	 */
	public interface JobDispatchConst
	{
////	    int GET_REPORTMODEL = 3;
////	    int GET_TICKETMODEL = 4;
//	    /** 从DB表TableConst.DEFAULT_T_SYS_CONF中获取系统基本配置信息 */
//	    int GET_CONF = 11;
//	    /** 常用更新 */
//	    int SINGLE_SQL_UPDATE = 13;
//	    /** 用List的方式更新数据库 */
//	    int BATCH_SQL_UPDATE = 15;
	//    
//	    int GET_SQL_RESULT_BAT = 17;
	    
	    /** 默认获取数据库数据 */
		int GET_DATA = 22;
	//	
//		/** 系统日志管理 */
//		int SYS_LOG = 23;
	}
}
